class ToolTip {
  
  // 
  int PADDING = 10; // padding around text
  float FONTSIZE = 12;
  color FONTCOLOR = color(255);
  float TEXTLEADING = FONTSIZE * 1.3;
  int MAX_WIDTH = 100;
  int[] durations = {0,4,4,0,20,20}; // transition-durations for phases 0-5
  
  
  Thing th; // follower
  String label = "";
  boolean visible;
  float fade = 0; // 0..100
  float wScale = 0; // 0..100
  float w,h; // width / heigth of bg
  int age, timeDiff;
  int phase = 0;
  
  
  ToolTip(String _label){
    textFont(font,FONTSIZE);
    label = wordWrap(_label, MAX_WIDTH);
    w = max(textWidth(label), MAX_WIDTH) + PADDING*2;
    h = split(label, "\n").length * TEXTLEADING + FONTSIZE/4 + PADDING*2;
  }
  
  void followThing(Thing _th){
    th = _th;
  }
  
  void draw() {
    if (visible || phase > 0) {
      tick(); // calculate animation-params
      
      // calculate position of top-left-tooltip-corner
      //PVector p = new PVector(th.x, th.y);
      PVector p = new PVector(mouseX, mouseY);
//      boolean rt = (p.x+w < width && p.y-h > 0);
//      boolean lt = (p.x-w > 0 && p.y-h > 0);
//      boolean rb = (p.x+w < width && p.y+h < height);
//      boolean lb = (p.x-w > 0 && p.y+h < height);
      
      if      (p.x+w < width && p.y-h > 0) p = new PVector(p.x, p.y-h);
      else if (p.x-w > 0 && p.y-h > 0) p = new PVector(p.x-w, p.y-h);
      else if (p.x+w < width && p.y+h < height) p = new PVector(p.x, p.y);
      else if (p.x-w > 0 && p.y+h < height) p = new PVector(p.x-w, p.y);
      
      
      pushMatrix();
      translate(p.x, p.y);
      
      // draw background
      fill(50);
      rect(0, 0, w*wScale/100, h);
      
      // draw typo
      fill(FONTCOLOR, fade);
      textFont(font,FONTSIZE);
      textLeading(TEXTLEADING);
      text(label, PADDING, PADDING+FONTSIZE);
      popMatrix();
    }
  }
  
  void setVisible(boolean flag){
    visible = flag;
    if (flag) {
      age = 0; 
      phase = 1; timeDiff = age;
    }else{
      if (phase==3) phase = 4; timeDiff = age;
      
    }
  }
  
  
  
  // private
  
  void tick(){
    int t = age-timeDiff; // local time in phase from 0..durations[phase]
    
    // 1. background
    if (phase == 1) {
      wScale = Cubic.easeInOut(t, 0, 100, durations[phase]);
      fade = 0;
      if (t > durations[phase]) {
        phase = 2; timeDiff = age;
      }
    // 2. fade in typo
    }else if (phase == 2) {
      wScale = 100;
      fade = Cubic.easeInOut(t, 0, 100, durations[phase]);
      if (t > durations[phase]) {
        phase = 3; timeDiff = age;
      }
    }else if (phase == 3 && !visible) {   
      phase = 4;
      
    // 4. fade out typo
    }else if (phase == 4) {
      fade = 100 - Cubic.easeInOut(t, 0, 100, durations[phase]);
      if (t > durations[phase]) {
        phase = 5; timeDiff = age;
      }
    // 5. background
    }else if (phase == 5) {
      wScale = 100 - Cubic.easeInOut(t, 0, 100, durations[phase]);
      if (t > durations[phase]) {
        phase = 0; //timeDiff = age;
      }
    }
    
    age++; 
  }
  
  /**
    modified version from:
    wordwrap taken from http://processinghacks.com/hacks:wordwrap
    @author Daniel Shiffman
  */
  // Function to return an wrapped String
  // Arguments: String to be wrapped, maximum width in pixels of each line
  String wordWrap(String s, int maxWidth) {
    String a = "";
    float w = 0;    // Accumulate width of chars
    int i = 0;      // Count through chars
    int rememberSpace = 0; // Remember where the last space was
    int watchdog = s.length()*2;
    // As long as we are not at the end of the String
    while (i < s.length() && watchdog > 0) {
      // Current char
      char c = s.charAt(i);
      
      w += textWidth(c); // accumulate width
      if (c == ' ') rememberSpace = i; // Are we a blank space?
      if (w > maxWidth) {  // Have we reached the end of a line?
        if (rememberSpace == 0) rememberSpace = i; // no space found: force break
        String sub = s.substring(0,rememberSpace);
        
        // Chop off space at beginning
        if (sub.length() > 0 && sub.charAt(0) == ' ') sub = sub.substring(1,sub.length());
        // Add substring to the list
        a += sub+"\n";
        
        // Reset everything
        s = s.substring(rememberSpace,s.length());
        i = 0;
        w = 0;
        rememberSpace = 0;
        
      } else if (c == '\n') { 
        String sub = s.substring(0,i);
        // Chop off space at beginning
        if (sub.length() > 0 && sub.charAt(0) == ' ') sub = sub.substring(1,sub.length());
        // Add substring to the list
        a += sub+"\n";
        
        // Reset everything
        s = s.substring(i+1, s.length());
        i = 0;
        w = 0;
        
      } else {
        i++;  // Keep going!
      }
      watchdog--;
    }
   
    // Take care of the last remaining line
    if (s.length() > 0 && s.charAt(0) == ' ') s = s.substring(1,s.length());
    
    a += s+"\n";
       
    return a;
  }
  
}



